package grape.auth.rest;

import com.fasterxml.classmate.TypeResolver;
import com.google.common.collect.Ordering;
import com.google.common.collect.Sets;
import grape.common.rest.common.SwaggerConfig;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.stereotype.Component;
import springfox.documentation.builders.ApiDescriptionBuilder;
import springfox.documentation.builders.AuthorizationScopeBuilder;
import springfox.documentation.builders.OperationBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.ApiListingScannerPlugin;
import springfox.documentation.spi.service.contexts.DocumentationContext;
import springfox.documentation.spring.web.readers.operation.CachingOperationNameGenerator;

import java.util.*;

/**
 * 认证额外的接口文档
 * Created by yangwei
 * Created at 2020/7/31 16:20
 */
@Component
public class AuthSwaggerAddtion implements ApiListingScannerPlugin, SwaggerConfig {

    @Override
    public List<ApiDescription> apply(DocumentationContext documentationContext) {
        return new ArrayList<ApiDescription>(
                Arrays.asList(
                        login()
                )

        );
    }

    /**
     * 登录接口
     * @return
     */
    private ApiDescription login(){
        ApiDescriptionBuilder apiDescriptionBuilder = new ApiDescriptionBuilder(Ordering.from(Comparator.comparing(operation -> operation.getMethod())));
        return apiDescriptionBuilder
                .groupName("认证应用")
                .path("/oauth/token")

                .operations(Arrays.asList(new OperationBuilder(new CachingOperationNameGenerator())
                        .method(HttpMethod.POST)//http请求类型
                        .produces(Sets.newHashSet(MediaType.APPLICATION_JSON_VALUE))
                        .tags(Sets.newHashSet("oauth2 认证相关接口"))//归类标签
                        .summary("登录接口")
                        .responseModel(new ModelRef("org.springframework.security.oauth2.common.OAuth2AccessToken"))
                        .parameters(
                                Arrays.asList(
                                        authorization(),
                                        parameterBuilder()
                                                .description("oauth2 scope，如read")//参数描述
                                                .type(resolvedTypeString())//参数数据类型
                                                .name("scope")//参数名称
                                                .parameterType(parameter_type_query)//参数类型
                                                .required(true)//是否必填
                                                .modelRef(modelRefString()) //参数数据类型
                                                .build(),
                                        parameterBuilder()
                                                .description("oauth2鉴权方式,grant_type=passowrd(后台登录用户名密码)、wx_mp_code(微信公众号授权登录)、front_user_password(前端登录用户名密码)、front_user_third（前端第三方登录如：微信、qq、微博等）")//参数描述
                                                .type(resolvedTypeString())//参数数据类型
                                                .name("grant_type")//参数名称
                                                .parameterType(parameter_type_query)//参数类型
                                                .required(true)//是否必填
                                                .modelRef(modelRefString()) //参数数据类型
                                                .build(),

                                        parameterBuilder()
                                                .description("用户名,后台/前端用户登录=username，微信公众号授权登录=appCode(配置的appid或编码)，前端第三方登录=openId+空格+登录标识字典")
                                                .type(resolvedTypeString())
                                                .name("username")
                                                .parameterType(parameter_type_form)
                                                .required(true)
                                                .modelRef(modelRefString()) 
                                                .build(),
                                        parameterBuilder()
                                                .description("密码,后台/前端用户=password,微信公众号授权登录=code（重定向回来的code），前端第三方登录=用户信息的json字符串，内容参见grape.base.service.frontuser.dto.FrontUserThirdCreateParam")
                                                .type(resolvedTypeString())
                                                .name("password")
                                                .parameterType(parameter_type_form)
                                                .required(true)
                                                .modelRef(modelRefString()) 
                                                .build())
                                )
                        .build())).build();

    }

    @Override
    public boolean supports(DocumentationType documentationType) {
        return DocumentationType.SWAGGER_2.equals(documentationType);
    }
}
